// 13.1 拷贝、赋值与销毁
/**
 * 我们将以最基本的操作——拷贝构造函数、拷贝赋值运算符和析构函数作为开始。我们在13.6节（第470页）中将介绍移动操作（新标准所引入的操作）。
 */

#include <iterator>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
#include <string>
#include <array>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
using std::swap;
using std::vector, std::list, std::deque, std::forward_list, std::string, std::array, std::stack, std::queue;
#include "../Chapter07/Sales_data.h"
#include <iostream>
using std::begin, std::cbegin, std::end, std::cend, std::find, std::accumulate, std::equal, std::fill, std::fill_n, std::back_inserter;
using std::cin, std::cout, std::endl;
using std::copy, std::replace, std::replace_copy;
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <memory>
#include <new>
using namespace std;

// 演示析构函数
class Foo
{
public:
    ~Foo();                      // 析构函数
    Foo &operator=(const Foo &); // 赋值运算符
    Foo();                       // 默认构造函数
    Foo(const Foo &);            // 拷贝构造函数
};

// 演示等价于合成析构函数的析构函数
class Foo1{
public:
    ~Foo1() {} // 成员被自动销毁，除此之外不需要做其他事情
};

int main()
{
    // 13.1.4 三/五法则
    // 如前所述，有三个基本操作可以控制类的拷贝操作：拷贝构造函数、拷贝赋值运算符和析构函数。
    // 而且，在新标准下，一个类还可以定义一个移动构造函数和一个移动赋值运算符。

    // 需要析构函数的类也需要拷贝和赋值操作
    // 当我们决定一个类是否要定义它自己版本的拷贝控制成员时，一个基本原则是首先确定这个类是否需要一个析构函数。
    // 通常，对析构函数的需求要比对拷贝构造函数或赋值运算符的需求更为明显。
    // 如果这个类需要一个析构函数，我们几乎可以肯定它也需要一个拷贝构造函数和一个拷贝赋值运算符。
    // 我们在练习中用过的HasPtr类是一个好例子（参见13.1.1节，第443页）。这个类在构造函数中分配动态内存。
    // 合成析构函数不会delete一个指针数据成员。因此，此类需要定义一个析构函数来释放构造函数分配的内存。
    // 如果一个类需要自定义析构函数，几乎可以肯定它也需要自定义拷贝赋值运算符和拷贝构造函数。

    // 需要拷贝操作的类也需要赋值操作，反之亦然
    // 如果一个类需要一个拷贝构造函数，几乎可以肯定它也需要一个拷贝赋值运算符。反之亦然
    // 然而，无论是需要拷贝构造函数还是需要拷贝赋值运算符都不必然意味着也需要析构函数。




    return 0;
}